/*
     raw os - Copyright (C)  Lingjun Chen(jorya_txj).

    This file is part of raw os.

    raw os is free software; you can redistribute it it under the terms of the 
    GNU General Public License as published by the Free Software Foundation; 
    either version 3 of the License, or  (at your option) any later version.

    raw os is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
    without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
    See the GNU General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program. if not, write email to jorya.txj@gmail.com
                                      ---

    A special exception to the LGPL can be applied should you wish to distribute
    a combined work that includes raw os, without being obliged to provide
    the source code for any proprietary components. See the file exception.txt
    for full details of how and when the exception can be applied.
*/


/* 	2012-8  Created by jorya_txj
  *	xxxxxx   please added here
  */


#include  <stdio.h>
#include  <string.h>
#include  <ctype.h>
#include  <stdlib.h>

#include "def.h"
#include "option.h"
#include "2440addr.h"     
#include "2440lib.h"
#include "2440slib.h"     
#include "mmu.h" 
#include "timer_bsp.h"

#include "raw_api.h"
#include <mm/raw_page.h>
#include <mm/raw_malloc.h>


#define  TEST_TASK_STK_SIZE 2048

PORT_STACK test_task_stack1[TEST_TASK_STK_SIZE];
PORT_STACK test_task_stack2[TEST_TASK_STK_SIZE];
PORT_STACK test_task_stack3[TEST_TASK_STK_SIZE];
PORT_STACK test_task_stack4[TEST_TASK_STK_SIZE];
PORT_STACK test_task_stack5[TEST_TASK_STK_SIZE];
PORT_STACK test_task_stack6[TEST_TASK_STK_SIZE];
PORT_STACK test_task_stack7[TEST_TASK_STK_SIZE];
PORT_STACK test_task_stack8[TEST_TASK_STK_SIZE];


RAW_TASK_OBJ 		test_task_obj[10];


volatile unsigned long  t1;
volatile unsigned long  t2;
volatile unsigned long  t3;
volatile unsigned long  t4;
volatile unsigned long  t5;
volatile unsigned long  t6;
volatile unsigned long  flag1;
volatile unsigned long  flag2;
volatile unsigned long  flag3;
volatile unsigned long  flag4;



extern unsigned int read_cpsr(void);
extern void write_cpsr(unsigned int );

void test1_task5(void * pParam) ;
void test1_task6(void * pParam) ;

extern void global_mem_init(unsigned int start_mem, unsigned int end_mem);


void test1_task1(void * pParam) 
{	
	
	RAW_U32 stack_size;
	void *test_addr;
	void *test_addr2;
	
	Timer0Init();
	global_mem_init(0x30000000, 0x32000000);

	test_addr = raw_page_allocate(1);
	test_addr2 = raw_malloc(1011);
	
	Uart_Printf("test_addr is %p\n", test_addr);
	Uart_Printf("test_addr2 is %p\n", test_addr2);
	
	while(1) {
		
		raw_task_stack_check(&test_task_obj[1], 	&stack_size);
		Uart_Printf("t11* stack_size is %d\n", stack_size);

		Uart_Printf("t1 is %x\n", t1);
		Uart_Printf("t2 is %x\n", t2);
		Uart_Printf("t3 is %x\n", t3);
		Uart_Printf("t4 is %x\n", t4);
		Uart_Printf("t5 is %x\n", t5);
		Uart_Printf("t6 is %x\n", t6);

		raw_disable_sche();
		t1++;
		if(t1 == 3)
		{
			flag1 = 1;
		}
		else if(t1 == 6)
		{
			flag2 = 1; 
		}
		else if(t1 == 9)
		{
			flag3 = 1; 
		}
		else if(t1  == 12)
		{
			flag4  = 1;
		}
		else if(t1 == 15)
		{
			//raw_task_delete(&test_task_obj[3]);
			//raw_task_delete(&test_task_obj[4]);
			//Uart_Printf("task3 and task4 are deleted by task1!!!\n");
			raw_task_create(&test_task_obj[5], (RAW_U8  *)"task5", 0,
	                         30, 10,   test_task_stack5, 
	                         TEST_TASK_STK_SIZE ,  test1_task5, 1); 

			raw_task_create(&test_task_obj[6], (RAW_U8  *)"task6", 0,
	                         30, 10,   test_task_stack6, 
	                         TEST_TASK_STK_SIZE ,  test1_task6, 1); 
		}
		
		if(t1 == 20)
		{
			raw_set_sched_way(&test_task_obj[6],SCHED_FIFO);
		}
		else if(t1 == 30)
		{
			raw_set_sched_way(&test_task_obj[5],SCHED_FIFO); 
		}
		else if(t1 == 40)
		{
			raw_set_sched_way(&test_task_obj[6],SCHED_RR);
		}
		else if(t1  == 50)
		{
			raw_set_sched_way(&test_task_obj[5],SCHED_RR);
		}
		else if(t1 == 60)
		{
			raw_task_time_slice_change(&test_task_obj[6],300);
		}
		else if(t1 == 70)
		{
			//raw_task_delete(&test_task_obj[5]);
			//raw_task_delete(&test_task_obj[6]);
			//Uart_Printf("task5 and task6 are deleted by task1!!!\n");
		}
		if((t1 >= 20) && (t1 <= 50) && (t1 % 10 == 0))
		{
			Uart_Printf("task55555's schedule way is: %s\n", test_task_obj[5].sched_way == 1u? "SCHED_FIFO" : "SCHED_RR");
			Uart_Printf("task666666's schedule way is: %s\n", test_task_obj[6].sched_way == 1u? "SCHED_FIFO" : "SCHED_RR");
		}
		
		raw_enable_sche();
		raw_sleep(10);	
		
	}
	
}



void test1_task2(void * pParam) 
{	

	while(1) {
		 raw_disable_sche();
		t2++;		
		raw_enable_sche();

		Uart_Printf("task22 is running...\n");
		raw_sleep(10);	
	}
}



void test1_task3(void * pParam) 
{	
	
	while(1) {
		 raw_disable_sche();
		t3++;

		if(flag1 == 1)
		{
			flag1 = 0; 
			raw_task_suspend(&test_task_obj[2]);
			Uart_Printf("task333 suspended task22!!!\n");
		}
		else if(flag2 == 1)
		{
			flag2 = 0; 
			raw_task_resume(&test_task_obj[2]);
			Uart_Printf("task333 resumed task22!!!\n");
		}		
		raw_enable_sche();

		
		if(flag4 == 1)
		{
			flag4 = 0;
			//raw_task_delete(&test_task_obj[2]);
			//Uart_Printf("task2 delete by task3!!!\n");
		}

		Uart_Printf("task333 is running...\n");
		raw_sleep(1);	
	}
}


void test1_task4(void * pParam) 
{	
	RAW_U8 old_priority;	
	while(1) {
		raw_disable_sche();
		t4++;		
		raw_enable_sche();

		if(flag3 == 1)
		{	
			flag3 = 0;
			raw_task_priority_change(&test_task_obj[4], 20, &old_priority);
			Uart_Printf("task4444 change itself priority to 20\n");
			raw_task_priority_change(&test_task_obj[3], 20, &old_priority);
			Uart_Printf("task4444 change task3's priority to 20\n");
		}
		Uart_Printf("task4444111 is running...\n");
		Uart_Printf("task4444222 is running...\n");
		Uart_Printf("task4444333 is running...\n");
		Uart_Printf("task4444444 is running...\n");
		Uart_Printf("task4444555 is running...\n");
		raw_sleep(5);	
	}
}

void test1_task5(void * pParam) 
{
	while(1) {
		 raw_disable_sche();
		t5++;		
		raw_enable_sche();
		Uart_Printf("task55555 is running...\n");
		raw_sleep(5);	
	}
}

void test1_task6(void * pParam) 
{	
	while(1) {
		 raw_disable_sche();
		t6++;		
		raw_enable_sche();
		Uart_Printf("task666666 is running...\n");
		raw_sleep(5);	
	}
}


RAW_QUEUE app_queue;
void *queue2_storge[20];
unsigned int msg1;

void test1_task7(void * pParam) 
	
{	
	unsigned int *data2;
	
	raw_queue_create(&app_queue, "driver_queue", (RAW_VOID **)&queue2_storge, 20);
	
	while(1) {

		raw_queue_receive (&app_queue, RAW_WAIT_FOREVER, (RAW_VOID **)&data2);
		raw_disable_sche();
		Uart_Printf("******data2********* is %x\n", *data2);
		raw_enable_sche();
		
	}
}



void test1_task8(void * pParam) 
{	
	
	while(1) {

		raw_queue_end_post(&app_queue, &msg1);
		msg1++;
		raw_sleep(1);
		
	}
}



extern RAW_U8 test_started;
void task_test1()
{

	if (test_started) {

		return;

	}

	test_started = 1;
	
	raw_task_create(&test_task_obj[1], (RAW_U8  *)"task1", 0,
	                         5, 0,  test_task_stack1, 
	                         TEST_TASK_STK_SIZE ,  test1_task1, 1); 




	raw_task_create(&test_task_obj[2], (RAW_U8  *)"task2", 0,
	                         10, 10,   test_task_stack2, 
	                         TEST_TASK_STK_SIZE ,  test1_task2, 1); 




	raw_task_create(&test_task_obj[3], (RAW_U8  *)"task3", 0,
	                         20, 10,   test_task_stack3, 
	                         TEST_TASK_STK_SIZE ,  test1_task3, 1); 



	raw_task_create(&test_task_obj[4], (RAW_U8  *)"task4", 0,
	                         30, 10,   test_task_stack4, 
	                         TEST_TASK_STK_SIZE ,  test1_task4, 1); 
	


	raw_task_create(&test_task_obj[7], (RAW_U8  *)"task5", 0,
	                         40, 10,   test_task_stack7, 
	                         TEST_TASK_STK_SIZE ,  test1_task7, 1); 



	raw_task_create(&test_task_obj[8], (RAW_U8  *)"task6", 0,
	                         41, 10,   test_task_stack8, 
	                         TEST_TASK_STK_SIZE ,  test1_task8, 1); 
	
	

}

